#!/bin/bash

# K8s集群一键部署脚本
# 自动完成所有节点的准备和部署工作

set -e

# 配置文件路径
CONFIG_FILE="./k8s-config.conf"
LOG_FILE="/var/log/k8s-cluster-deploy.log"

# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

# 日志函数
log() {
    local level=$1
    shift
    local message="$*"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    
    case $level in
        "INFO")
            echo -e "${BLUE}[INFO]${NC} $message" | tee -a $LOG_FILE
            ;;
        "SUCCESS")
            echo -e "${GREEN}[SUCCESS]${NC} $message" | tee -a $LOG_FILE
            ;;
        "WARNING")
            echo -e "${YELLOW}[WARNING]${NC} $message" | tee -a $LOG_FILE
            ;;
        "ERROR")
            echo -e "${RED}[ERROR]${NC} $message" | tee -a $LOG_FILE
            ;;
    esac
}

# 错误处理函数
error_exit() {
    log "ERROR" "$1"
    log "ERROR" "集群部署失败，请检查日志: $LOG_FILE"
    exit 1
}

# 检查配置文件
check_config() {
    if [ ! -f "$CONFIG_FILE" ]; then
        error_exit "配置文件不存在: $CONFIG_FILE"
    fi
    
    # 加载配置文件
    source "$CONFIG_FILE"
    
    log "SUCCESS" "配置文件加载成功"
    log "INFO" "集群名称: $CLUSTER_NAME"
    log "INFO" "Master节点: $MASTER_HOSTNAME ($MASTER_IP)"
    log "INFO" "Worker1节点: $WORKER1_HOSTNAME ($WORKER1_IP)"
    log "INFO" "Worker2节点: $WORKER2_HOSTNAME ($WORKER2_IP)"
}

# 检查root权限
check_root() {
    if [ "$EUID" -ne 0 ]; then
        error_exit "请使用root用户运行此脚本"
    fi
    log "SUCCESS" "权限检查通过"
}

# 检查必要脚本
check_scripts() {
    local required_scripts=(
        "prepare_server.sh"
        "configure_hostnames.sh"
        "configure_network.sh"
        "quick_deploy.sh"
        "download_k8s.sh"
    )
    
    for script in "${required_scripts[@]}"; do
        if [ ! -f "$script" ]; then
            error_exit "缺少必要脚本: $script"
        fi
    done
    
    # 给脚本执行权限
    chmod +x *.sh
    
    log "SUCCESS" "所有必要脚本检查完成"
}

# 准备所有节点
prepare_all_nodes() {
    log "INFO" "开始准备所有节点..."
    
    # 准备Master节点
    log "INFO" "准备Master节点: $MASTER_HOSTNAME ($MASTER_IP)"
    ./prepare_server.sh --hostname="$MASTER_HOSTNAME" --ip="$MASTER_IP"
    
    # 准备Worker节点
    log "INFO" "准备Worker1节点: $WORKER1_HOSTNAME ($WORKER1_IP)"
    ./prepare_server.sh --hostname="$WORKER1_HOSTNAME" --ip="$WORKER1_IP"
    
    log "INFO" "准备Worker2节点: $WORKER2_HOSTNAME ($WORKER2_IP)"
    ./prepare_server.sh --hostname="$WORKER2_HOSTNAME" --ip="$WORKER2_IP"
    
    log "SUCCESS" "所有节点准备完成"
}

# 配置所有节点主机名
configure_all_hostnames() {
    log "INFO" "配置所有节点主机名..."
    
    # 配置Master节点
    log "INFO" "配置Master节点主机名"
    ./configure_hostnames.sh --node-type=master
    
    # 配置Worker节点
    log "INFO" "配置Worker1节点主机名"
    ./configure_hostnames.sh --node-type=worker1
    
    log "INFO" "配置Worker2节点主机名"
    ./configure_hostnames.sh --node-type=worker2
    
    log "SUCCESS" "所有节点主机名配置完成"
}

# 配置所有节点网络
configure_all_networks() {
    log "INFO" "配置所有节点网络..."
    
    # 配置Master节点网络
    log "INFO" "配置Master节点网络"
    ./configure_network.sh --node-type=master --ip="$MASTER_IP"
    
    # 配置Worker节点网络
    log "INFO" "配置Worker1节点网络"
    ./configure_network.sh --node-type=worker1 --ip="$WORKER1_IP"
    
    log "INFO" "配置Worker2节点网络"
    ./configure_network.sh --node-type=worker2 --ip="$WORKER2_IP"
    
    log "SUCCESS" "所有节点网络配置完成"
}

# 下载K8s安装包
download_k8s_packages() {
    log "INFO" "下载K8s安装包..."
    
    if [ ! -f "./download_k8s.sh" ]; then
        error_exit "未找到下载脚本"
    fi
    
    ./download_k8s.sh
    
    log "SUCCESS" "K8s安装包下载完成"
}

# 传输安装包到所有节点
transfer_packages() {
    log "INFO" "传输安装包到所有节点..."
    
    local package_dir="k8s-offline-packages"
    
    if [ ! -d "$package_dir" ]; then
        error_exit "未找到安装包目录: $package_dir"
    fi
    
    # 传输到Master节点
    log "INFO" "传输安装包到Master节点: $MASTER_IP"
    scp -r "$package_dir" "$MASTER_USER@$MASTER_IP:/root/"
    
    # 传输到Worker节点
    log "INFO" "传输安装包到Worker1节点: $WORKER1_IP"
    scp -r "$package_dir" "$WORKER1_USER@$WORKER1_IP:/root/"
    
    log "INFO" "传输安装包到Worker2节点: $WORKER2_IP"
    scp -r "$package_dir" "$WORKER2_USER@$WORKER2_IP:/root/"
    
    log "SUCCESS" "安装包传输完成"
}

# 部署Master节点
deploy_master() {
    log "INFO" "部署Master节点..."
    
    # 在Master节点执行部署
    ssh "$MASTER_USER@$MASTER_IP" << EOF
        cd /root/$package_dir
        ./quick_deploy.sh master
EOF
    
    log "SUCCESS" "Master节点部署完成"
}

# 部署Worker节点
deploy_workers() {
    log "INFO" "部署Worker节点..."
    
    # 获取join命令
    local join_cmd=$(ssh "$MASTER_USER@$MASTER_IP" "cat /root/join-command.txt")
    
    if [ -z "$join_cmd" ]; then
        error_exit "无法获取join命令"
    fi
    
    # 解析join命令
    local token=$(echo $join_cmd | grep -o '--token [^ ]*' | cut -d' ' -f2)
    local cert_hash=$(echo $join_cmd | grep -o '--discovery-token-ca-cert-hash sha256:[^ ]*' | cut -d':' -f2)
    
    if [ -z "$token" ] || [ -z "$cert_hash" ]; then
        error_exit "无法解析join命令"
    fi
    
    # 部署Worker1节点
    log "INFO" "部署Worker1节点"
    ssh "$WORKER1_USER@$WORKER1_IP" << EOF
        cd /root/$package_dir
        ./quick_deploy.sh worker $WORKER1_IP
EOF
    
    # 部署Worker2节点
    log "INFO" "部署Worker2节点"
    ssh "$WORKER2_USER@$WORKER2_IP" << EOF
        cd /root/$package_dir
        ./quick_deploy.sh worker $WORKER2_IP
EOF
    
    log "SUCCESS" "Worker节点部署完成"
}

# 安装网络插件
install_network_plugin() {
    log "INFO" "安装网络插件..."
    
    # 在Master节点安装网络插件
    ssh "$MASTER_USER@$MASTER_IP" << EOF
        cd /root/$package_dir
        ./quick_deploy.sh network
EOF
    
    log "SUCCESS" "网络插件安装完成"
}

# 验证集群
verify_cluster() {
    log "INFO" "验证集群状态..."
    
    # 在Master节点验证集群
    ssh "$MASTER_USER@$MASTER_IP" << EOF
        cd /root/$package_dir
        ./quick_deploy.sh verify
EOF
    
    log "SUCCESS" "集群验证完成"
}

# 生成部署报告
generate_report() {
    local report_file="/tmp/k8s-cluster-deploy-report-$(date +%Y%m%d-%H%M%S).txt"
    
    log "INFO" "生成部署报告: $report_file"
    
    {
        echo "K8s集群部署报告"
        echo "生成时间: $(date)"
        echo "集群名称: $CLUSTER_NAME"
        echo "=========================================="
        echo ""
        
        echo "集群节点信息:"
        echo "Master节点: $MASTER_HOSTNAME ($MASTER_IP)"
        echo "Worker1节点: $WORKER1_HOSTNAME ($WORKER1_IP)"
        echo "Worker2节点: $WORKER2_HOSTNAME ($WORKER2_IP)"
        echo ""
        
        echo "集群配置:"
        echo "K8s版本: $K8S_VERSION"
        echo "Pod网络CIDR: $POD_NETWORK_CIDR"
        echo "服务CIDR: $SERVICE_CIDR"
        echo ""
        
        echo "部署状态:"
        echo "✓ 所有节点准备完成"
        echo "✓ 主机名配置完成"
        echo "✓ 网络配置完成"
        echo "✓ K8s组件安装完成"
        echo "✓ 网络插件安装完成"
        echo "✓ 集群验证完成"
        echo ""
        
        echo "访问信息:"
        echo "Master节点SSH: ssh $MASTER_USER@$MASTER_IP"
        echo "Worker1节点SSH: ssh $WORKER1_USER@$WORKER1_IP"
        echo "Worker2节点SSH: ssh $WORKER2_USER@$WORKER2_IP"
        echo ""
        echo "集群管理:"
        echo "kubectl配置: 在Master节点执行 'kubectl get nodes'"
        echo "集群状态: 在Master节点执行 'kubectl cluster-info'"
        echo ""
        
    } > $report_file
    
    log "SUCCESS" "部署报告已生成: $report_file"
}

# 显示使用说明
show_usage() {
    echo "K8s集群一键部署脚本"
    echo ""
    echo "用法:"
    echo "  $0 [选项]"
    echo ""
    echo "选项:"
    echo "  --prepare-only        仅准备节点环境"
    echo "  --deploy-only         仅部署K8s集群"
    echo "  --skip-download       跳过下载步骤"
    echo "  --skip-transfer       跳过传输步骤"
    echo "  --help                显示帮助信息"
    echo ""
    echo "示例:"
    echo "  $0                    # 完整部署流程"
    echo "  $0 --prepare-only      # 仅准备环境"
    echo "  $0 --deploy-only       # 仅部署集群"
}

# 主函数
main() {
    log "INFO" "开始K8s集群一键部署..."
    log "INFO" "部署日志: $LOG_FILE"
    
    # 解析命令行参数
    local prepare_only=false
    local deploy_only=false
    local skip_download=false
    local skip_transfer=false
    
    while [[ $# -gt 0 ]]; do
        case $1 in
            --prepare-only)
                prepare_only=true
                shift
                ;;
            --deploy-only)
                deploy_only=true
                shift
                ;;
            --skip-download)
                skip_download=true
                shift
                ;;
            --skip-transfer)
                skip_transfer=true
                shift
                ;;
            --help)
                show_usage
                exit 0
                ;;
            *)
                echo "未知参数: $1"
                show_usage
                exit 1
                ;;
        esac
    done
    
    # 执行部署步骤
    check_root
    check_config
    check_scripts
    
    if [ "$prepare_only" = true ]; then
        # 仅准备环境
        prepare_all_nodes
        configure_all_hostnames
        configure_all_networks
        log "SUCCESS" "节点环境准备完成！"
        exit 0
    fi
    
    if [ "$deploy_only" = true ]; then
        # 仅部署集群
        deploy_master
        deploy_workers
        install_network_plugin
        verify_cluster
        generate_report
        log "SUCCESS" "K8s集群部署完成！"
        exit 0
    fi
    
    # 完整部署流程
    log "INFO" "开始完整部署流程..."
    
    # 准备环境
    prepare_all_nodes
    configure_all_hostnames
    configure_all_networks
    
    # 下载安装包
    if [ "$skip_download" = false ]; then
        download_k8s_packages
    fi
    
    # 传输安装包
    if [ "$skip_transfer" = false ]; then
        transfer_packages
    fi
    
    # 部署集群
    deploy_master
    deploy_workers
    install_network_plugin
    verify_cluster
    
    # 生成报告
    generate_report
    
    log "SUCCESS" "K8s集群一键部署完成！"
    log "INFO" "请查看部署报告了解详细信息"
}

# 运行主函数
main "$@"
